/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package com.soa.util.wx;

import com.lianzt.commondata.AbstractCommonData;
import com.lianzt.commondata.CommonDataElement;
import com.lianzt.commondata.DataConvertFactory;
import com.lianzt.exception.InstanceDataException;
import com.lianzt.rest.TraffRest;
import com.lianzt.util.DateUtil;
import com.lianzt.util.MD5;
import com.lianzt.util.StringUtil;
import com.soa.exception.GlobalException;
import static com.soa.service.BaseService.getSession;
import com.soa.util.SystemUtil;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.UnsupportedEncodingException;
import java.net.SocketTimeoutException;
import java.net.URL;
import java.net.URLConnection;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.logging.Level;
import java.util.regex.Pattern;
import javax.annotation.Resource;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;

/**
 * 工具类
 * @author zuotai
 */
@Component
public class TrffUtil {

    public int serialCache = 1000;         //流水号
    private final Logger log = LoggerFactory.getLogger(TrffUtil.class);
    private final String BASE_SCOPE_URL = "https://open.weixin.qq.com/connect/oauth2/authorize?appid=%s&redirect_uri=%s&response_type=code&scope=snsapi_base&state=lianzt#wechat_redirect";       //微信的授权url
    private final String BASE_SERVICE_URL = "http%3a%2f%2fapp.jtgzfw.com%2fkslp%2fwx%2fsnsapi.do%3fservice%3d";      //应用内的授权url，在后面直接跟服务码
    /**
     * 超时时间
     */
    protected final int TIMEOUT = 10000;

    /**
     * 获取流水号
     * 说明：当要调整为分布式部署时，需要修改此函数，流水号后几位要保存在redis中，每次获取之后都进行加一操作（直接在redis中加1），并在每天凌晨重置。
     * 流水号格式为：A + yyyyMMddHHmmss + N + xxxx； N为服务器节点，xxxx为4位序列号
     *
     * @return
     */
    public String getSerialNum() {
        try {
            if (serialCache >= 9999) {
                serialCache = 1000;
            } else {
                serialCache++;
            }
            return "A" + DateUtil.detaledLshFormat(new Date()) + SystemUtil.getSysConfig("server_node") + serialCache;
        } catch (Exception e) {
            log.error("流水号更新异常 : " + e);
            throw new GlobalException(999995);     //生成流水号异常
        }
    }

    /**
     * 把驾驶证状态转为汉字
     * @param zt
     * @return
     */
    public String drvZtToDesc(String zt) {
        if (StringUtil.isNull(zt)) {
            return null;
        }
        StringBuilder desc = new StringBuilder();
        for (int i = 0, len = zt.length(); i < len; i++) {
            if (desc.length() > 0) {
                desc.append(",");
            }
            desc.append(SystemUtil.getColValueDesc("drv.zt", Character.toString(zt.charAt(i))));
        }
        return desc.toString();
    }

    /**
     * 获取授权URL
     * @param url
     * @return
     */
    public String getScopeUrl(String service) {
        return String.format(BASE_SCOPE_URL, SystemUtil.getSysConfig("wx_appid"), (BASE_SERVICE_URL + service));
    }

    /**
     * 校验微信登录
     * @param in
     */
    public void checkWxLogin(AbstractCommonData in) {
        AbstractCommonData ses = getSession(in);
        String openid = ses.getStringValue("openid");
        if (StringUtil.isNull(openid)) {
            throw new GlobalException(400015);      //登录信息已超时，请关闭后重新打开
        }
    }
    
    /**
     *
     * @param pushUrl
     * @param json
     * @return
     * @throws IOException
     */
    public String pushJSON(String pushUrl, String json) throws IOException {
        
        if (StringUtil.isNull(json) || StringUtil.isNull(pushUrl)) {
            return null;
        }
        URL url = null;
        URLConnection con = null;
        BufferedWriter bw = null;
        BufferedReader br = null;
        //签名
        String str = signJson(json);
        log.info("push url={}, json={}", pushUrl, json);
        try {
            url = new URL(pushUrl);
            con = url.openConnection();
            /**
             * 然后把连接设为输出模式。URLConnection通常作为输入来使用，比如下载一个Web页。
             * 通过把URLConnection设为输出，你可以把数据向你个Web页传送。下面是如何做：
             */
            con.setDoOutput(true);
            con.setConnectTimeout(20000);
            con.addRequestProperty("Timestamp", str.split(",")[0]);
            con.addRequestProperty("Sesame", str.split(",")[1]);
            con.setReadTimeout(20000);
            con.addRequestProperty("Content-Type", "application/json");
            con.addRequestProperty("Content-Length", Integer.toString(json.length()));
            /**
             * 最后，为了得到OutputStream，简单起见，把它约束在Writer并且放入POST信息中，例如： ...
             */
            bw = new BufferedWriter(new OutputStreamWriter(con.getOutputStream(), "UTF-8"));
            StringBuilder sb = new StringBuilder();
            sb.append(json);
            bw.write(sb.toString());

            bw.flush();

            String tmpStr;
            sb = new StringBuilder();

            br = new BufferedReader(new InputStreamReader(con.getInputStream(), "utf-8"));
            while ((tmpStr = br.readLine()) != null) {
                sb.append(tmpStr);
            }
            log.info("RETURN url={} res={}", pushUrl, sb);
            return sb.toString();
        } finally {
            if (bw != null) {
                try {
                    bw.close();
                } catch (Exception e) {
                    log.warn("关闭连接异常：" + e.toString());
                }
            }
            if (br != null) {
                try {
                    br.close();
                } catch (Exception e) {
                    log.warn("关闭连接异常：" + e.toString());
                }
            }
        }
    }

    /**
     * 内网接口调用
     *
     * @param abs 要传递的参数
     *
     */
    public String Nwjkdy(AbstractCommonData abs) {
        String url = SystemUtil.getSysConfig("nwjk_url");
        String json = DataConvertFactory.praseNormJson(abs);
        String serviceName = abs.getStringValue("serviceName");
        url=url+serviceName+".do";
        String str = "";
        try {
            str = pushJSON(url, json);
        } catch (IOException ex) {
            java.util.logging.Logger.getLogger(TrffUtil.class.getName()).log(Level.SEVERE, null, ex);
        }
        return str;
    }
    /**
     * 生成签名
     * @return 
     */
    public String signJson(String json){
        long time =  System.currentTimeMillis();
        String key ="514En*mJ0hVeL&e0M!fFQ3o&xhAch#zC";
        String str = json+"^"+time+"^"+key;
        String sign="";
        try {
             sign= MD5.digestAsHex(str.getBytes("UTF-8"));
        } catch (UnsupportedEncodingException ex) {
            java.util.logging.Logger.getLogger(TrffUtil.class.getName()).log(Level.SEVERE, null, ex);
        }
        
        return time+","+sign;
    }

    public static void main(String[] args) throws UnsupportedEncodingException {
//        String baseScopeUrl = "https://open.weixin.qq.com/connect/oauth2/authorize?appid=%s&redirect_uri=%s&response_type=code&scope=snsapi_base&state=lianzt#wechat_redirect";       //微信的授权url
//        String baseServiceUrl = "http://125.46.83.214/kslp/wx/snsapi.do?service=S40006&appid=gh_b4ae2d084ffd";
//        baseServiceUrl = URLEncoder.encode(baseServiceUrl, "utf-8");
//        System.out.println(System.currentTimeMillis());
    }
}
